﻿#include <thirdparty/fist-log.h>

#include <cppcoro/sync_wait.hpp>

#include "task_manager.h"
#include "task_info.h"
#include "task_conf.h"

CTaskManager::CTaskManager()
    : m_thread(new std::thread(&CTaskManager::SimpleCoThread, this))
    , m_network_thread(new std::thread(&CTaskManager::NetworkCoThread, this))
    , m_conf_parser(new CTaskConfParser)
{
    m_thread->detach();
}
CTaskManager::~ CTaskManager()
{
    delete m_thread;
    delete m_conf_parser;
}

bool CTaskManager::Init()
{
    if (!m_conf_parser->Load("../config/server/core/task.xml")) {
        return false;
    }

    return true;
}

void CTaskManager::Update()
{
    m_conf_parser->Update();
}

void CTaskManager::Destroy()
{
    
}

int CTaskManager::PushTask(Task&& task)
{
    if (m_tasks.size() > 5000) {
        m_task_wait.set();
        return TASK_TOO_MANY;
    }
    m_tasks.emplace(task);
    m_task_wait.set();
    return TASK_OK;
}

int CTaskManager::PushNetworkTask(Task&& task)
{
    if (m_network_tasks.size() > 5000) {
        m_network_task_wait.set();
        return TASK_TOO_MANY;
    }
    m_network_tasks.emplace(task);
    m_network_task_wait.set();
    return TASK_OK;
}

const TaskConf* CTaskManager::conf()
{
    return m_conf_parser->conf();
}

void CTaskManager::SimpleCoThread()
{
    sync_wait(SimpleCoMain());
}

cppcoro::task<> CTaskManager::SimpleCoMain()
{
    while (true) {
        if (m_tasks.empty()) {
            co_await m_task_wait;
        }
        m_task_wait.reset();
        Task task = m_tasks.front();
        m_tasks.pop();
        co_await task();
    }
}

void CTaskManager::NetworkCoThread()
{
    sync_wait(NetworkCoMain());
}

cppcoro::task<> CTaskManager::NetworkCoMain()
{
    while (true) {
        if (m_network_tasks.empty()) {
            co_await m_network_task_wait;
        }
        m_network_task_wait.reset();
        Task task = m_network_tasks.front();
        m_network_tasks.pop();
        co_await task();
    }
}
